from django.utils import timezone
from decimal import Decimal
import re
import pytz
from rest_framework import serializers
from apps.address.models import Address
from apps.schedules.models import TimeSlot
from .models import DjChefOrderStatusLog, DjChefOrder, Order, OrderItem, OrderStatusLog
from apps.chefs.serializers import SimpleChefSerializer, ChefConsumerSerializer
from apps.accounts.serializers import SimpleUserSerializer
from django.contrib.auth import get_user_model
from django.db import transaction 
from .utils import get_wechat_config
import logging
logger = logging.getLogger(__name__) 

class OrderItemSerializer(serializers.ModelSerializer):
    total_price = serializers.DecimalField(
        max_digits=10, decimal_places=2, read_only=True
    )

    class Meta:
        model = OrderItem
        fields = ['dish_id', 'name', 'quantity', 'price', 'image', 'total_price']
        read_only_fields = ['total_price']

    def validate_quantity(self, value):
        if value <= 0:
            raise serializers.ValidationError('数量必须为正数')
        return value

    def validate_price(self, value):
        if value < 0:
            raise serializers.ValidationError('价格不能为负数')
        return value


class OrderStatusLogSerializer(serializers.ModelSerializer):
    from_status_display = serializers.CharField(source='get_from_status_display', read_only=True)
    to_status_display = serializers.CharField(source='get_to_status_display', read_only=True)
    changed_by_name = serializers.SerializerMethodField()
    changed_by_avatar = serializers.SerializerMethodField()

    class Meta:
        model = OrderStatusLog
        fields = [
            'id', 'order', 'from_status', 'to_status',
            'from_status_display', 'to_status_display',
            'changed_by', 'changed_by_name', 'changed_by_avatar',
            'note', 'created_at', 'ip_address'
        ]
        read_only_fields = fields

    def get_changed_by_name(self, obj):
        if obj.changed_by:
            return obj.changed_by.username
        return '系统自动'

    def get_changed_by_avatar(self, obj):
        if obj.changed_by and hasattr(obj.changed_by, 'avatar') :
            return obj.changed_by.avatar
        return None


class OrderSerializer(serializers.ModelSerializer):
    items = OrderItemSerializer(many=True)
    status_logs = OrderStatusLogSerializer(many=True, read_only=True)
    customer = serializers.StringRelatedField()
    chef = ChefConsumerSerializer(read_only=True)  # 明确指定read_only
    chef_contact = serializers.SerializerMethodField()
    dish_images_approved = serializers.SerializerMethodField()
    chef_background_approved = serializers.SerializerMethodField()
    dishes = OrderItemSerializer(source='items', many=True, read_only=True)  # 避免重复序列化
    booked_time = serializers.SerializerMethodField(read_only=True)
    time_slot = serializers.StringRelatedField(read_only=True)
    payment_method = serializers.CharField(read_only=True)
    pay_time = serializers.SerializerMethodField(read_only=True)
    # 新增地址信息（从address_id关联的Address模型获取address_detail）
    address_detail = serializers.SerializerMethodField()
    # 补充联系电话（假设从customer或order自身获取，根据实际模型调整）
    contact_phone = serializers.SerializerMethodField()

    class Meta:
        model = Order
        fields = [
            'id', 'customer', 'chef', 'status', 'items', 'subtotal', 'order_number', 'dishes',
            'service_fee', 'total_amount', 'special_requests', 'is_accompany_meal', 'chef_contact',
            'status_logs', 'booked_time', 'time_slot', 'chef_id', 'pay_params', 'payment_method', 
            'complete_time','pay_time', 'created_at', 'updated_at', 'dish_images_approved',
            'chef_background_approved', 'address_detail', 'contact_phone'  # 新增地址和电话字段
        ]
        read_only_fields = ['status_logs', 'created_at', 'updated_at', 'booked_time', 'time_slot']

    def get_address_detail(self, obj):
        """从address_id关联的Address模型获取地址详情"""
        if hasattr(obj, 'address_id') and obj.address_id:
            try:
                # 修正Address模型导入路径（根据实际项目结构调整）
                from apps.address.models import Address  # 常见正确路径
                address = Address.objects.get(id=obj.address_id)
                return address.address_detail
            except (ImportError, Address.DoesNotExist):
                return None
        return None

    def get_contact_phone(self, obj):
        """获取厨师的联系电话（从厨师关联对象的phone_number字段获取）"""
        if hasattr(obj, 'chef') and hasattr(obj.chef, 'phone_number'):
            return obj.chef.phone_number
        return None

    def get_dish_images_approved(self, obj):
        if not self.context.get('check_image_approval'):
            return None
            
        from apps.menu.models import DjDishImage
        approved_status = {}
        for item in obj.items.all():  # 直接使用items
            dish_image = DjDishImage.objects.filter(
                dish_id=item.dish_id, 
                is_primary=True
            ).first()
            approved_status[item.dish_id] = dish_image.is_approved if dish_image else False
        return approved_status
    
    def get_chef_background_approved(self, obj):
        if not self.context.get('check_image_approval'):
            return None
        # 修复：直接访问厨师的background_approved字段（根据实际模型调整）
        return getattr(obj.chef, 'background_approved', False)
    
    def get_chef_contact(self, obj):
        if self.context.get('hide_chef_contact', False):
            return None
        # 修复：使用phone_number字段（与ChefConsumerSerializer保持一致）
        contact_phone = getattr(obj.chef, 'phone_number', None)
        if contact_phone:
            return {
                'phone': contact_phone,
                'is_virtual': False  # 可根据实际业务调整
            }
        return None
    
    def get_pay_time(self, obj):
        """将支付时间转换为上海时区并格式化"""
        return self._convert_to_shanghai_tz(obj.pay_time)
    
    def get_booked_time(self, obj):
        return self._convert_to_shanghai_tz(obj.booked_time)

    def get_created_at(self, obj):
        return self._convert_to_shanghai_tz(obj.created_at)

    def get_updated_at(self, obj):
        return self._convert_to_shanghai_tz(obj.updated_at)

    def _convert_to_shanghai_tz(self, dt):
        """将UTC时间转换为Asia/Shanghai时区并格式化"""
        if not dt:
            return None
        shanghai_tz = pytz.timezone('Asia/Shanghai')
        return dt.astimezone(shanghai_tz).isoformat()

class OrderCreateSerializer(serializers.ModelSerializer):
    items = OrderItemSerializer(many=True)  # 正确嵌套订单项序列化器
    address_detail = serializers.CharField(write_only=True)
    time_slot_id = serializers.IntegerField(write_only=True)

    class Meta:
        model = Order
        fields = ['id',
            'chef', 'items', 'special_requests', 
            'address_id', 'address_detail', 'booked_time', 'payment_method', 
            'is_consumer_mini_program', 'time_slot_id'
        ]
        
    def validate(self, data):
        """验证档期是否属于当前订单的厨师，且状态为可用"""
        chef = data['chef']
        time_slot_id = data['time_slot_id']
        
        try:
            time_slot = TimeSlot.objects.get(id=time_slot_id)
        except TimeSlot.DoesNotExist:
            raise serializers.ValidationError({"time_slot_id": "无效的档期ID"})
        
        # 验证1：档期必须属于当前订单的厨师
        if time_slot.chef != chef:
            raise serializers.ValidationError({"time_slot_id": "档期不属于当前厨师"})
        
        # 验证2：档期必须处于可用状态
        if time_slot.status != 'available':
            raise serializers.ValidationError({"time_slot_id": "档期已被占用或不可用"})
        
        return data
    
    def create(self, validated_data):
        with transaction.atomic():
            # 1. 提取并移除地址文本、档期ID、订单项（只提取一次items）
            address_detail = validated_data.pop('address_detail').strip()
            user = self.context['request'].user
            time_slot_id = validated_data.pop('time_slot_id')
            time_slot = TimeSlot.objects.get(id=time_slot_id) 
            
            # 关键修复：只提取一次items，并验证非空
            items_data = validated_data.pop('items', [])
            if not items_data:
                raise serializers.ValidationError({"items": "订单项不能为空"})
            
            # 2. 查找或创建地址
            address, created = Address.objects.get_or_create(
                user=user,
                address_detail=address_detail,
                defaults={}
            )
            if created:
                logger.info(f"为用户[{user.id}]创建新地址: {address_detail}")
            else:
                logger.info(f"复用用户[{user.id}]已有地址: {address_detail}")

            # 3. 关联地址到订单
            validated_data['address'] = address

            # 4. 计算金额（使用已提取的items_data）
            is_consumer = validated_data.pop('is_consumer_mini_program', True)
            
            try:
                subtotal = sum(
                    Decimal(str(item['quantity'])) * Decimal(str(item['price'])) 
                    for item in items_data  # 直接使用之前提取的items_data
                )
                service_fee = subtotal * Decimal('0.1')
                total_amount = subtotal + service_fee
            except (KeyError, TypeError, ValueError) as e:
                logger.error(f"金额计算失败: {str(e)}")
                subtotal = Decimal('0')
                service_fee = Decimal('0')
                total_amount = Decimal('0')

            # 移除可能的冗余字段
            for field in ['subtotal', 'service_fee', 'total_amount']:
                validated_data.pop(field, None)

            # 5. 创建订单
            order = Order.objects.create(
                **validated_data,
                is_consumer_mini_program=is_consumer,
                subtotal=subtotal,
                service_fee=service_fee,
                total_amount=total_amount,
                time_slot=time_slot
            )

            # 6. 更新档期状态
            time_slot.order = order
            time_slot.status = 'booked'
            time_slot.save()

            # 7. 创建订单项（使用已提取的items_data）
            for item_data in items_data:  # 直接使用之前提取的items_data
                OrderItem.objects.create(order=order,** item_data)

            return order

class TimeSlotSerializer(serializers.Serializer):
    id = serializers.CharField()
    display = serializers.CharField()
    value = serializers.CharField()

class OrderStatusUpdateSerializer(serializers.Serializer):
    status = serializers.ChoiceField(choices=Order.STATUS_CHOICES)
    
    def validate_status(self, value):
        # 可以添加更多状态验证逻辑
        return value
    
    def update(self, instance, validated_data):
        # 状态变更逻辑在perform_update中处理
        return instance

class ChefServiceOrderItemSerializer(serializers.ModelSerializer):
    dish_image_approved = serializers.SerializerMethodField()
    
    class Meta:
        model = OrderItem
        fields = ['id', 'dish_id', 'name', 'quantity', 'price', 'notes', 'customer_name', 'customer_contact', 'dish_image_approved']
    
    def get_dish_image_approved(self, obj):
        # 检查菜品图片审核状态
        from apps.menu.models import DjDishImage
        dish_image = DjDishImage.objects.filter(dish_id=obj.dish_id, is_primary=True).first()
        return dish_image.is_approved if dish_image else False
    
    def get_customer_contact(self, obj):
        # 根据上下文决定是否隐藏联系方式
        if self.context.get('hide_contact', False):
            return None
        return {
            'phone': obj.customer_contact_number or obj.customer.phone,
            'is_virtual': bool(obj.customer_contact_number)
        }

class ChefServiceOrderSerializer(serializers.ModelSerializer):
    chef = SimpleChefSerializer(read_only=True)
    customer = SimpleUserSerializer(read_only=True)
    items = ChefServiceOrderItemSerializer(many=True, source='order_items')
    chef_background_approved = serializers.SerializerMethodField()
    wechat_pay_params = serializers.SerializerMethodField()
    is_consumer_mini_program = serializers.BooleanField(write_only=True, default=True)
    
    class Meta:
        model = Order
        fields = [
            'id', 'customer', 'chef', 'status', 'items', 'subtotal',
            'service_fee', 'total_amount', 'special_requests', 'chef_name', 'chef_contact', 'delivery_time', 'status_logs',
            'created_at', 'updated_at', 'dish_images_approved',
            'chef_background_approved', 'wechat_pay_params', 'is_consumer_mini_program'
        ]
        read_only_fields = ['status_logs', 'created_at', 'updated_at', 'wechat_pay_params']
    
    def get_wechat_pay_params(self, obj):
        # 只在待支付状态返回微信支付参数
        if obj.status != 'pending' or obj.payment_method != 'wechat':
            return None
            
        request = self.context.get('request')
        if not request:
            return None
            
        # 根据小程序类型获取配置
        is_consumer = obj.is_consumer_mini_program
        app_type = 'consumer' if is_consumer else 'provider'
        wechat_config = get_wechat_config(app_type)
        
        # 调用微信支付服务类
        from .services.wechat_pay_service import WechatPayService
        pay_service = WechatPayService(wechat_config)
        try:
            wechat_pay_params = pay_service.unified_order(obj)
            return wechat_pay_params
        except Exception as e:
            return None
    
    def get_chef_background_approved(self, obj):
        # 检查厨师背景图审核状态
        return obj.chef.background_approved if obj.chef.background else False

class OrderStatusCountSerializer(serializers.Serializer):
    pending = serializers.IntegerField()
    paid = serializers.IntegerField()
    preparing = serializers.IntegerField()
    completed = serializers.IntegerField()
    cancelled = serializers.IntegerField()
    rejected = serializers.IntegerField()

#chef
User = get_user_model()

class DjChefOrderStatusLogSerializer(serializers.ModelSerializer):
    """订单状态日志序列化器（嵌套使用）"""
    class Meta:
        model = DjChefOrderStatusLog
        fields = ['id', 'from_status', 'to_status', 'changed_by', 'note', 'created_at']
        read_only_fields = fields  # 日志为只读


class DjChefOrderSerializer(serializers.ModelSerializer):
    """厨师订单序列化器"""
    # 嵌套显示顾客信息（简化，只展示必要字段）
    customer_info = serializers.SerializerMethodField()
    # 嵌套显示状态日志
    status_logs = DjChefOrderStatusLogSerializer(many=True, read_only=True)
    # 原始订单ID（如需关联查看）
    original_order_id = serializers.IntegerField(source='original_order.id', read_only=True)
    background = serializers.URLField(source='chef.background', read_only=True)
    time_slot_id = serializers.IntegerField(source='original_order.time_slot.id', read_only=True)

    class Meta:
        model = DjChefOrder
        fields = [
            'id', 'order_number', 'status', 'status_logs',
            'chef', 'customer', 'customer_info','background',
            'service_date', 'service_time', 'service_address', 'guest_count',
            'chef_fee', 'ingredients_fee', 'chef_income',
            'original_order_id','time_slot_id',
            'confirmed_at', 'completed_at', 'created_at', 'updated_at'
        ]
        read_only_fields = [
            'order_number', 'created_at', 'updated_at', 
            'confirmed_at', 'completed_at', 'chef'  # 厨师字段只读
        ]

    def get_customer_info(self, obj):
        """获取顾客信息并加密手机号"""
        customer = obj.customer
        phone = customer.phone if hasattr(customer, 'phone') else None
        
        # 手机号加密处理（示例：保留首尾，中间用*替换，如138****5678）
        if phone:
            # 简单加密：仅展示首尾各3位，中间用*代替（根据需求调整加密强度）
            if re.match(r'^\d{11}$', phone):  # 假设是11位手机号
                phone = phone[:3] + '****' + phone[-4:]
            else:
                phone = '****'  # 非标准格式手机号统一处理
        
        return {
            'id': customer.id,
            'username': customer.username,
            'nickname': customer.nickname,
            'phone': phone  # 返回加密后的手机号
        }

class OrderItemMiniSerializer(serializers.ModelSerializer):
    """原始订单菜品的简化序列化器"""
    class Meta:
        model = OrderItem
        fields = ['id', 'dish_id','name', 'quantity', 'price']

#djchef
class DishItemSerializer(serializers.ModelSerializer):
    totalPrice = serializers.SerializerMethodField()  # 前端需要的小驼峰格式

    class Meta:
        model = OrderItem
        fields = ['dish_id', 'name', 'image', 'quantity', 'price', 'totalPrice']

    def get_totalPrice(self, obj):
        return obj.total_price  # 复用OrderItem的total_price属性


# 客户信息序列化器
class CustomerSerializer(serializers.Serializer):
    name = serializers.CharField(source='customer.nickname')
    avatar = serializers.CharField(source='customer.avatar', allow_null=True, required=False)
    phone = serializers.SerializerMethodField()

    def get_phone(self, obj):
        """对手机号进行加密处理，保留首尾数字，中间用*替换"""
        phone = getattr(obj.customer, 'phone', None)
        if not phone:
            return None
        
        # 匹配11位手机号格式
        if re.match(r'^\d{11}$', phone):
            return f"{phone[:3]}****{phone[-4:]}"
        # 非标准格式手机号统一显示为****
        return "****"


# 主订单序列化器
class DjChefOrderDetailSerializer(serializers.ModelSerializer):
    # 状态文本映射（zh/en）
    statusTextZh = serializers.SerializerMethodField()
    statusTextEn = serializers.SerializerMethodField()
    statusDescZh = serializers.SerializerMethodField()
    statusDescEn = serializers.SerializerMethodField()
    background = serializers.URLField(source='chef.background', read_only=True)
    # 客户信息
    customer = CustomerSerializer(source='*')  # 复用当前对象的customer关联
    
    # 订单基本信息
    #phone = serializers.CharField(source='original_order.customer_contact_number')
    note = serializers.CharField(source='original_order.special_requests', allow_null=True, required=False)
    service_date = serializers.DateField(format='%Y-%m-%d')  # 格式化日期
    service_time = serializers.TimeField(format='%H:%M')     # 格式化时间
    
    # 菜品清单
    dishes = DishItemSerializer(source='original_order.items', many=True)  # 关联OrderItem
    
    # 价格信息
    subtotal = serializers.DecimalField(source='original_order.subtotal', max_digits=10, decimal_places=2)
    serviceFee = serializers.DecimalField(source='original_order.service_fee', max_digits=10, decimal_places=2)

    # 订单明细
    orderNo = serializers.CharField(source='order_number')
    createTime = serializers.DateTimeField(source='original_order.created_at', format='%Y-%m-%d %H:%M')

    class Meta:
        model = DjChefOrder
        fields = ['id',
            'status', 'statusTextZh', 'statusTextEn', 'statusDescZh', 'statusDescEn','background',
            'customer', 'service_date', 'service_time', 'service_address', 'note',
            'dishes', 'subtotal', 'serviceFee', 'chef_income',
            'orderNo', 'createTime'
        ]

    # 状态文本映射逻辑（示例，根据实际业务调整）
    def get_statusTextZh(self, obj):
        status_map = {
            'pending': '待确认',
            'confirmed': '已预订',  # 对应前端booked状态
            'serving': '服务中',
            'completed': '已完成',
            'cancelled': '已取消'
        }
        return status_map.get(obj.status, obj.status)

    def get_statusTextEn(self, obj):
        status_map = {
            'pending': 'Pending',
            'confirmed': 'Booked',  # 对应前端booked状态
            'serving': 'Serving',
            'completed': 'Completed',
            'cancelled': 'Cancelled'
        }
        return status_map.get(obj.status, obj.status)

    # 状态描述映射（示例）
    def get_statusDescZh(self, obj):
        desc_map = {
            'pending': '请确认是否接单',
            'confirmed': '已确认接单，准备服务',
            'serving': '正在为客户提供服务',
            'completed': '服务已完成，可查看评价'
        }
        return desc_map.get(obj.status, '')

    def get_statusDescEn(self, obj):
        desc_map = {
            'pending': 'Please confirm to accept the order',
            'confirmed': 'Order confirmed, prepare for service',
            'serving': 'Providing service to customer',
            'completed': 'Service completed, check review'
        }
        return desc_map.get(obj.status, '')


# chefs/serializers.py
class DjChefOrderStatusUpdateSerializer(serializers.ModelSerializer):
    """仅用于更新订单状态的简化序列化器"""
    special_requests = serializers.CharField(source='original_order.special_requests', required=False)
    is_accompany_meal = serializers.BooleanField(source='original_order.is_accompany_meal', required=False)
    
    class Meta:
        model = DjChefOrder
        fields = ['id', 'status', 'special_requests', 'is_accompany_meal']
        read_only_fields = ['id']